home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / nxyplot / Source / FormatHandler.m < prev    next >
Text File  |  1992-11-23  |  18KB  |  532 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "FormatHandler.h"
  5. #import "Plot.h"
  6. #import "PlotView.h"
  7. #import "defs.h"
  8. #import <appkit/OpenPanel.h>
  9. #import <appkit/SavePanel.h>
  10. #import <appkit/Panel.h>
  11. #import <streams/streams.h>
  12. #import <strings.h>
  13. #import <appkit/color.h>
  14. #import <appkit/NXColorWell.h>
  15. #import <appkit/Button.h>
  16.  
  17. @implementation FormatHandler
  18.  
  19. // This is an attempt to get around an infinite loop that could otherwise result
  20. // when we try to read in an "old" format file with the "new" program.
  21. int cautious_read(NXStream *formatStream)
  22. {
  23.   int i;
  24.  
  25.   while(YES) {
  26.     i = NXGetc(formatStream);
  27.     if (i == ':') return 0;    /* good */
  28.     if (i == EOF) {
  29.       NXRunAlertPanel("Format File Read",
  30.               "Unexpected end of file while reading format file\n"
  31.               "(Perhaps you tried to read in an \"old\" format file)",
  32.               "OK", NULL, NULL);
  33.       return 1;
  34.     }
  35.   }
  36. }
  37.  
  38. - writeFormatData:(NXStream *)formatStream
  39. {
  40.   id  font;
  41.   int ncurves = [plotParam nCurvesTotal], i;
  42.   NXPoint   point;
  43.   NXRect    windowframe;
  44.   float r, g, b, a;
  45.   NXColor aColor;
  46.  
  47.   NXPrintf(formatStream, "xmin xmax xinc: %g %g %g\n", [plotParam provideXmin],
  48.        [plotParam provideXmax], [plotParam provideXinc]);
  49.   NXPrintf(formatStream, "ymin ymax yinc: %g %g %g\n", [plotParam provideYmin],
  50.        [plotParam provideYmax], [plotParam provideYinc]);
  51.   NXPrintf(formatStream, "xaxis: %s\n", [plotParam xaxisLog]? "log" : "linear");
  52.   NXPrintf(formatStream, "yaxis: %s\n", [plotParam yaxisLog]? "log" : "linear");
  53.  
  54.   NXPrintf(formatStream, "Main title: %s\n", [mainTitle stringValueAt:0]);
  55.   NXPrintf(formatStream, " Font and size: ");
  56.   font = [canvas provideMainTitleFont];
  57.   if (font == NULL)
  58.     NXPrintf(formatStream, "Helvetica 14.0\n");
  59.   else
  60.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  61.   point = [canvas provideMainTitleBoxOrigin];
  62.   NXPrintf(formatStream, " main title box origin: %f %f\n", point.x, point.y);  
  63.  
  64.   NXPrintf(formatStream, "X title: %s\n", [xTitle stringValueAt:0]);
  65.   NXPrintf(formatStream, " Font and size: ");
  66.   font = [canvas provideXTitleFont];
  67.   if (font == NULL)
  68.     NXPrintf(formatStream, "Helvetica %f\n", DEFAULTFONTSIZE);
  69.   else
  70.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  71.   point = [canvas provideXTitleBoxOrigin];
  72.   NXPrintf(formatStream, " x-title box origin: %f %f\n", point.x, point.y);  
  73.  
  74.   NXPrintf(formatStream, "Y title: %s\n", [yTitle stringValueAt:0]);
  75.   NXPrintf(formatStream, " Font and size: ");
  76.   font = [canvas provideYTitleFont];
  77.   if (font == NULL)
  78.     NXPrintf(formatStream, "Helvetica %f\n", DEFAULTFONTSIZE);
  79.   else
  80.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  81.   point = [canvas provideYTitleBoxOrigin];
  82.   NXPrintf(formatStream, " y-title box origin: %f %f\n", point.x, point.y);  
  83.  
  84.   NXPrintf(formatStream, "Legend on/off: %d\n", [legendOnOff state]);
  85.   NXPrintf(formatStream, "Legend Box on/off: %d\n",
  86.        [legendBoxOnOff state]);
  87.   NXPrintf(formatStream, "Legend title: %s\n", [legendTitle stringValueAt:0]);
  88.   NXPrintf(formatStream, " Font and size: ");
  89.   font = [canvas provideLegendTitleFont];
  90.   if (font == NULL)
  91.     NXPrintf(formatStream, "Helvetica %f\n", DEFAULTFONTSIZE);
  92.   else
  93.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  94.  
  95.   NXPrintf(formatStream, "Legend font and size: ");
  96.   font = [canvas provideLegendFont];
  97.   if (font == NULL)
  98.     NXPrintf(formatStream, "Helvetica %f\n", DEFAULTFONTSIZE);
  99.   else
  100.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  101.  
  102.   NXPrintf(formatStream, "No. of curves: %d\n", ncurves);
  103.   NXPrintf(formatStream, "Curve No.  Line type  Symbol type"
  104.        "         Color (R,G,B,A)          Title\n");
  105.   for (i = 0; i < ncurves; i++) {
  106.     aColor = [plotParam provideCurveColor:i];
  107. /* Convert to RGB for the sake of getting something human-readable */
  108.     NXConvertColorToRGBA(aColor, &r, &g, &b, &a);
  109.     NXPrintf(formatStream, "%4d %8d %10d %f %f %f %f %18s\n", i+1,
  110.          [plotParam providelinestyle:i], [plotParam providesymbolstyle:i],
  111.          r, g, b, a, [legendForm stringValueAt:i]);
  112.   }
  113.  
  114.   NXPrintf(formatStream, "Line thickness: %f\n", [lineThicknessText floatValue]);
  115.   NXPrintf(formatStream, "Symbol size: %f\n", [symbolSizeText floatValue]);
  116.  
  117.   NXPrintf(formatStream, "Grid on/off: %d\n", [gridOnOff state]);
  118.   NXPrintf(formatStream, "Grid dotted: %d\n", [gridDotted state]);
  119.   NXPrintf(formatStream, "Grid thickness: %f\n", [gridThicknessText floatValue]);
  120.  
  121.   NXPrintf(formatStream, "Border box on/off: %d\n",
  122.        [borderBoxOnOff state]);
  123.   NXPrintf(formatStream, "Border box thickness: %f\n",
  124.        [borderBoxThicknessText floatValue]);
  125.  
  126.   NXPrintf(formatStream, "Frame box on/off: %d\n",
  127.        [frameBoxOnOff state]);
  128.   NXPrintf(formatStream, "Frame box thickness: %f\n",
  129.        [frameBoxThicknessText floatValue]);
  130.  
  131.   NXPrintf(formatStream, "Axes on/off: %d\n", [axesOnOff state]);
  132.   NXPrintf(formatStream, "Axis thickness: %f\n", [axisThicknessText floatValue]);
  133.  
  134.   NXPrintf(formatStream, "Tic label font and size: ");
  135.   font = [canvas provideTicLabelFont];
  136.   if (font == NULL)
  137.     NXPrintf(formatStream, "Helvetica %f\n", DEFAULTFONTSIZE);
  138.   else
  139.     NXPrintf(formatStream, "%s %f\n", [font name], [font pointSize]);
  140.  
  141.   NXPrintf(formatStream, "Major tic marks on/off: %d\n",
  142.        [majorTicMarksOnOff state]);
  143.  
  144.   NXPrintf(formatStream, "Minor tic marks on/off: %d\n",
  145.        [minorTicMarksOnOff state]);
  146.  
  147.   NXPrintf(formatStream, "Tic mark length: %f\n",
  148.        [ticMarkLengthText floatValue]);
  149.  
  150.   NXPrintf(formatStream, "Tic mark thickness: %f\n",
  151.        [ticMarkThicknessText floatValue]);
  152.  
  153.   if (strncmp([ticMarkLocation title], "Axes", 4) == 0)
  154.     i = 0;
  155.   else if (strncmp([ticMarkLocation title], "Frame (2 sides)", 15) == 0)
  156.     i = 1;
  157.   else
  158.     i = 2;
  159.   NXPrintf(formatStream, "Tic mark location: %d\n", i);
  160.  
  161.   point = [canvas provideLegendBoxOrigin];
  162.   NXPrintf(formatStream, "Legend box origin: %f %f\n", point.x, point.y);
  163.  
  164.   [canvas provideWindowFrame:&windowframe];
  165.   NXPrintf(formatStream, "Window origin and size: %f %f %f %f\n",
  166.        windowframe.origin.x, windowframe.origin.y,
  167.        windowframe.size.width, windowframe.size.height);
  168.   aColor = [plotParam provideTextColor];
  169.   NXConvertColorToRGBA(aColor, &r, &g, &b, &a);
  170.   NXPrintf(formatStream, "Text color (r, g, b, a): %f %f %f %f\n",
  171.        r, g, b, a);
  172.   aColor = [plotParam provideBackgroundColor];
  173.   NXConvertColorToRGBA(aColor, &r, &g, &b, &a);
  174.   NXPrintf(formatStream, "Background color (r, g, b, a): %f %f %f %f\n",
  175.        r, g, b, a);
  176.  
  177. // Following is new for error bars:
  178.   NXPrintf(formatStream, "Error bar base width: %f\n",
  179.        [ebarBaseWidthText floatValue]);
  180.  
  181. // Following is new (placed here for backward compatibility)
  182.   NXPrintf(formatStream, "Legend transparency: %d\n", [legendOpaque state]);
  183.  
  184.   return self;
  185. }
  186.  
  187. #define READ_ONE_INT(x) if (cautious_read(formatStream) != 0) return self;\
  188.   NXScanf(formatStream, "%d\n", &x);
  189.  
  190. #define READ_ONE_FLOAT(x) if (cautious_read(formatStream) != 0) return self;\
  191.   NXScanf(formatStream, "%f\n", &x);
  192.  
  193. #define READ_STRING(s) if (cautious_read(formatStream) != 0) return self; \
  194.   while (NXGetc(formatStream) == ' ') \
  195.     ;                /* throw away spaces */ \
  196.   NXUngetc(formatStream);    /* but put that non-space back! */ \
  197.   for (i = 0; i < 1024  && (s[i]=NXGetc(formatStream)) != '\n'; i++) \
  198.     ;                /* everything up to newline */ \
  199.   s[i] = '\000';
  200.  
  201. #define READ_STRING_AND_FLOAT(s, x) \
  202.   if (cautious_read(formatStream) != 0) return self; \
  203.   while (NXGetc(formatStream) == ' ') \
  204.     ; \
  205.   NXUngetc(formatStream); \
  206.   (void) NXScanf(formatStream, "%s %f", s, &x); /* font and size */
  207.  
  208. - readFormatData:(NXStream *)formatStream
  209. {
  210.   char  string[1024];
  211.   double d1, d2, d3;
  212.   float  f1;
  213.   int   i, j, ncurves, curveno, linetype, symtype;
  214.   NXPoint point;
  215.   NXRect  windowframe;
  216.   float r, g, b, a;
  217.   NXColor aColor;
  218.  
  219.   if (cautious_read(formatStream) != 0) return self;
  220.   (void) NXScanf(formatStream, "%lf %lf %lf\n", &d1, &d2, &d3);
  221.   [plotParam resetXmin:d1];
  222.   [plotParam resetXmax:d2];
  223.   [plotParam resetXinc:d3];
  224.   if (cautious_read(formatStream) != 0) return self;
  225.   (void) NXScanf(formatStream, "%lf %lf %lf\n", &d1, &d2, &d3);
  226.   [plotParam resetYmin:d1];
  227.   [plotParam resetYmax:d2];
  228.   [plotParam resetYinc:d3];
  229.  
  230.   if (cautious_read(formatStream) != 0) return self;
  231.   (void) NXScanf(formatStream, "%s\n", string);
  232.   if (!strncmp(string, "log", 3))
  233.     [plotParam forceXaxisLog];
  234.   else
  235.     [plotParam forceXaxisLinear];
  236.  
  237.   if (cautious_read(formatStream) != 0) return self;
  238.   (void) NXScanf(formatStream, "%s\n", string);
  239.   if (!strncmp(string, "log", 3))
  240.     [plotParam forceYaxisLog];
  241.   else
  242.     [plotParam forceYaxisLinear];
  243.  
  244.   // Main title:
  245.   READ_STRING(string);
  246.   [mainTitle setStringValue:string at:0];
  247.   READ_STRING_AND_FLOAT(string, f1);
  248.   [canvas forceMainTitleFont:string :f1];
  249.   if (cautious_read(formatStream) != 0) return self;
  250.   (void) NXScanf(formatStream, "%f %f\n", &point.x, &point.y); /* maintitlebox */
  251.   [canvas forceMainTitleBoxOrigin:point];
  252.  
  253.   // X title:
  254.   READ_STRING(string);
  255.   [xTitle setStringValue:string at:0];
  256.   READ_STRING_AND_FLOAT(string, f1);
  257.   [canvas forceXTitleFont:string :f1];
  258.   if (cautious_read(formatStream) != 0) return self;
  259.   (void) NXScanf(formatStream, "%f %f\n", &point.x, &point.y); /* xtitlebox */
  260.   [canvas forceXTitleBoxOrigin:point];
  261.  
  262.   // Y title:
  263.   READ_STRING(string);
  264.   [yTitle setStringValue:string at:0];
  265.   READ_STRING_AND_FLOAT(string, f1);
  266.   [canvas forceYTitleFont:string :f1];
  267.   if (cautious_read(formatStream) != 0) return self;
  268.   (void) NXScanf(formatStream, "%f %f\n", &point.x, &point.y); /* ytitlebox */
  269.   [canvas forceYTitleBoxOrigin:point];
  270.  
  271.   // Legend on/off:
  272.   READ_ONE_INT(i);
  273.   [legendOnOff setState:i];
  274.  
  275.   // Legend Box on/off:
  276.   READ_ONE_INT(i);
  277.   [legendBoxOnOff setState:i];
  278.  
  279.   // Legend title:
  280.   READ_STRING(string);
  281.   [legendTitle setStringValue:string at:0];
  282.  
  283.   // Legend title font and size:
  284.   READ_STRING_AND_FLOAT(string, f1);
  285.   [canvas forceLegendTitleFont:string :f1];
  286.  
  287.   // Legend font:
  288.   READ_STRING_AND_FLOAT(string, f1);
  289.   [canvas forceLegendFont:string :f1];
  290.  
  291.   // Curves: No., line type, symbol type, colors, title
  292.   READ_ONE_INT(ncurves);
  293.   while (NXGetc(formatStream) != '\n')
  294.     ;
  295.   for (i = 0; i < ncurves; i++) {
  296.     NXScanf(formatStream, "%d %d %d", &curveno, &linetype, &symtype);
  297.     NXScanf(formatStream, "%f %f %f %f", &r, &g, &b, &a);
  298.     aColor = NXConvertRGBAToColor(r, g, b, a);
  299.     while (NXGetc(formatStream) == ' ')
  300.       ;
  301.     NXUngetc(formatStream);
  302.     for (j = 0; j < 1024  && (string[j]=NXGetc(formatStream)) != '\n'; j++)
  303.       ;                /* everything up to newline */
  304.     string[j] = '\000';
  305.     [legendForm setStringValue:string at:i];
  306.     [plotParam makeLineStyle:i :linetype];
  307.     [plotParam makeSymbolType:i :symtype];
  308.     [plotParam forceCurveColor:i :aColor];
  309.     [plotParam adjustLineStyleMatrix:i :linetype];
  310.     [plotParam adjustSymbolTypeMatrix:i :symtype];
  311.     if (i==0)
  312.       [curveColorWell setColor:aColor];
  313.   }
  314.   [plotParam redisplayLineStyleMatrix];
  315.   [plotParam redisplaySymbolTypeMatrix];
  316.   [curveNumber setIntValue:1];    /* the text field next to the curve color well */
  317.  
  318.   // Thickness:
  319.   READ_ONE_FLOAT(f1);
  320.   [lineThickness setFloatValue:ABS(f1)]; /* message slider and text field */
  321.   [lineThicknessText setFloatValue:ABS(f1)];
  322.  
  323.   // Symbol size:
  324.   READ_ONE_FLOAT(f1);
  325.   [symbolSize setFloatValue:ABS(f1)]; /* message slider and text field */
  326.   [symbolSizeText setFloatValue:ABS(f1)];
  327.  
  328.   // Grid on/off, dotted, and thickness:
  329.   READ_ONE_INT(i);
  330.   [gridOnOff setState:i];
  331.   // Here is where the "new" (version 1.7) format file begins to differ
  332.   // from the "old" (1.6); the new has "Grid dotted" here, the old has
  333.   // "Border box thickness"
  334.   //
  335.   // Read in one character:
  336.   i = NXGetc(formatStream);
  337.   if (i == 'B') {        /* old */
  338.     NXRunAlertPanel("Format File Read",
  339.             "Suspected \"old\" format file\n"
  340.             "Doing the best I can...",
  341.             "OK", NULL, NULL);
  342.   //Border box thickness
  343.     READ_ONE_FLOAT(f1);
  344.     [borderBoxThickness setFloatValue:ABS(f1)];    /* message slider and text field */
  345.   //Axes on/off
  346.     READ_ONE_INT(i);
  347.     [axesOnOff setState:i];
  348.   //Axis thickness
  349.     READ_ONE_FLOAT(f1);
  350.     [axisThickness setFloatValue:ABS(f1)]; /* message slider and text field */
  351.     [axisThicknessText setFloatValue:ABS(f1)];
  352.   //Tic label font and size
  353.     READ_STRING_AND_FLOAT(string, f1);
  354.     [canvas forceTicLabelFont:string :f1];
  355.   //Tic mark length
  356.     READ_ONE_FLOAT(f1);
  357.     [ticMarkLength setFloatValue:f1]; /* message slider and text field */
  358.     [ticMarkLengthText setFloatValue:f1];
  359.   //Minor tic marks on/off
  360.     READ_ONE_INT(i);
  361.     [minorTicMarksOnOff setState:i];
  362.   }
  363.   else {            /* new */
  364.     READ_ONE_INT(i);
  365.     [gridDotted setState:i];
  366.     READ_ONE_FLOAT(f1);
  367.     [gridThickness setFloatValue:ABS(f1)]; /* message slider and text field */
  368.     [gridThicknessText setFloatValue:ABS(f1)];
  369.  
  370.     // Border box on/off and thickness:
  371.     READ_ONE_INT(i);
  372.     [borderBoxOnOff setState:i];
  373.     READ_ONE_FLOAT(f1);
  374.     [borderBoxThickness setFloatValue:ABS(f1)];    /* message slider and text field */
  375.     [borderBoxThicknessText setFloatValue:ABS(f1)];
  376.  
  377.     // Frame box on/off and thickness:
  378.     READ_ONE_INT(i);
  379.     [frameBoxOnOff setState:i];
  380.     READ_ONE_FLOAT(f1);
  381.     [frameBoxThickness setFloatValue:ABS(f1)]; /* message slider and text field */
  382.     [frameBoxThicknessText setFloatValue:ABS(f1)];
  383.  
  384.     // Axes on/off and thickness:
  385.     READ_ONE_INT(i);
  386.     [axesOnOff setState:i];
  387.     READ_ONE_FLOAT(f1);
  388.     [axisThickness setFloatValue:ABS(f1)]; /* message slider and text field */
  389.     [axisThicknessText setFloatValue:ABS(f1)];
  390.  
  391.     // Tic label font and size:
  392.     READ_STRING_AND_FLOAT(string, f1);
  393.     [canvas forceTicLabelFont:string :f1];
  394.  
  395.     // Major tic marks on/off:
  396.     READ_ONE_INT(i);
  397.     [majorTicMarksOnOff setState:i];
  398.  
  399.     // Minor tic marks on/off:
  400.     READ_ONE_INT(i);
  401.     [minorTicMarksOnOff setState:i];
  402.  
  403.     // Tic mark length:
  404.     READ_ONE_FLOAT(f1);
  405.     [ticMarkLength setFloatValue:f1]; /* message slider and text field */
  406.     [ticMarkLengthText setFloatValue:f1];
  407.  
  408.     // Tic mark thickness:
  409.     READ_ONE_FLOAT(f1);
  410.     [ticMarkThickness setFloatValue:f1]; /* message slider and text field */
  411.     [ticMarkThicknessText setFloatValue:f1];
  412.  
  413.     // Tic mark location: 0=axes, 1=frame (2 sides), 2=frame (4 sides)
  414.     READ_ONE_INT(i);
  415.     if (i==0)
  416.       [ticMarkLocation setTitle:"Axes"];
  417.     else if (i==1)
  418.       [ticMarkLocation setTitle:"Frame (2 sides)"];
  419.     else
  420.       [ticMarkLocation setTitle:"Frame (4 sides)"];
  421.   }
  422.   // Legend Box origin:
  423.   if (cautious_read(formatStream) != 0) return self;
  424.   (void) NXScanf(formatStream, "%f %f\n", &point.x, &point.y);
  425.   [canvas forceLegendBoxOrigin:point];
  426.  
  427.   // Window origin and size:
  428.   if (cautious_read(formatStream) != 0) return self;
  429.   (void) NXScanf(formatStream, "%f %f %f %f\n", &windowframe.origin.x,
  430.          &windowframe.origin.y, &windowframe.size.width,
  431.          &windowframe.size.height);
  432.   [canvas forceWindowFrame:&windowframe];
  433.  
  434.   // Text color and background color:
  435.   if (cautious_read(formatStream) != 0) return self;
  436.   (void) NXScanf(formatStream, "%f %f %f %f\n", &r, &g, &b, &a);
  437.   aColor = NXConvertRGBAToColor(r, g, b, a);
  438.   [plotParam forceTextColor:aColor];
  439.   [textColorWell setColor:aColor];
  440.   if (cautious_read(formatStream) != 0) return self;
  441.   (void) NXScanf(formatStream, "%f %f %f %f\n", &r, &g, &b, &a);
  442.   aColor = NXConvertRGBAToColor(r, g, b, a);
  443.   [plotParam forceBackgroundColor:aColor];
  444.   [backgroundColorWell setColor:aColor];
  445.   NXPing();
  446.  
  447.   // Following is new for error bars:
  448.   // Error bar base width
  449.   READ_ONE_FLOAT(f1);
  450.   [ebarBaseWidth setFloatValue:f1]; /* message slider and text field */
  451.   [ebarBaseWidthText setFloatValue:f1];
  452.   NXPing();
  453.  
  454.   // Following is new (should go with legend material above this,
  455.   // but would be impossible to achieve backward compatibility of
  456.   // format files.
  457.   READ_ONE_INT(i);
  458.   [legendOpaque setState:i];
  459.  
  460.   return self;
  461. }
  462.  
  463. - getOpenFileName:(char *)name
  464. {
  465.   static const char *const fileTypes[2] = {NULL, NULL};
  466.   id    openPanel = [[OpenPanel new] allowMultipleFiles:NO];
  467.  
  468.   [openPanel setAccessoryView:nil]; /* may have to clean out an accessory view */
  469.   [openPanel setTitle:"Open"];        /* make sure title is OK (cf. binary open) */
  470.   if ([openPanel runModalForTypes:fileTypes]) {
  471.     strncpy(name, [openPanel filename], 1024);
  472.   }
  473.   return self;
  474. }
  475.  
  476. - getSaveFileName:(char *)name
  477. {
  478.   id savePanel = [[SavePanel new] setRequiredFileType:""];
  479.  
  480.   [savePanel setTitle:"Save Format"]; /* make sure title is correct */
  481.   if ([savePanel runModal]) {
  482.     strncpy(name, [savePanel filename], 1024);
  483.   }
  484.   return self;
  485. }
  486.  
  487. - writeFormatFile:sender
  488. {
  489.   char  fname[1024];
  490.   NXStream *formatStream;
  491.  
  492.   // Get a filename:
  493.   [self getSaveFileName:fname];
  494.   // Get a stream:
  495.   if ((formatStream = NXOpenMemory(NULL, 0, NX_WRITEONLY)) == NULL)  {
  496.     NXRunAlertPanel("Write Format", "Cannot open memory for %s",
  497.             "OK", NULL, NULL, fname);
  498.     return self;
  499.   }
  500.   // Write the data:
  501.   [self writeFormatData:formatStream];
  502.  
  503.   // Save the file which was memory-mapped:
  504.   NXFlush(formatStream);
  505.   NXSaveToFile(formatStream, fname);
  506.   NXClose(formatStream);
  507.  
  508.   return self;
  509. }
  510.  
  511. - readFormatFile:sender
  512. {
  513.   char  fname[1024];
  514.   NXStream *formatStream;
  515.  
  516.   // Get a filename:
  517.   [self getOpenFileName:fname];
  518.   // Get a stream:
  519.   if ((formatStream = NXMapFile(fname, NX_READONLY)) == NULL)  {
  520.     return self;
  521.   }
  522.   // Read the data:
  523.   [self readFormatData:formatStream];
  524.  
  525.   // Redraw automatically:
  526.   [plotParam drawPlot:self];
  527.   return self;
  528. }
  529.  
  530.  
  531. @end
  532.